#include "rs485_dev.h"
#include <QMessageBox>
#include <iostream>

using std::cout;
using std::endl;

qint8 rs485_dev::recv_cnt = 0;
qint8 rs485_dev::recv_data_bit_len = 8;

qint8 rs485_dev::getRecv_data_bit_len() const
{
    return recv_data_bit_len;
}

rs485_dev::rs485_dev(QString serialName,QObject *parent) : QObject(parent)
{
    //创建串口对象
    this->serialPort = new QSerialPort(serialName,this);
    //设置串口名称
    this->serialPort->setPortName(serialName);
    //设置波特率
    this->serialPort->setBaudRate(static_cast<qint32>(9600));
    //设置数据位数
    this->serialPort->setDataBits(QSerialPort::Data8);
    //设置奇偶校验
    this->serialPort->setParity(QSerialPort::NoParity);
    //设置停止位
    this->serialPort->setStopBits(QSerialPort::OneStop);
    //设置流控制
    this->serialPort->setFlowControl(QSerialPort::NoFlowControl);
    //打开串口
    if(!this->serialPort->open(QIODevice::ReadWrite))
    {
        QMessageBox::about(nullptr,"错误","串口无法打开，可能串口已经被占用");
    }
    //关联信号与槽
    connect(this->serialPort,&QSerialPort::readyRead,this,&rs485_dev::serialPortReadyRead);
}

rs485_dev::rs485_dev(QSerialPort *serialPort)
{
    this->serialPort = serialPort;
    //打开串口
    if(!this->serialPort->open(QIODevice::ReadWrite))
    {
        QMessageBox::about(nullptr,"错误","串口无法打开，可能串口已经被占用");
    }
    //关联信号与槽
    connect(this->serialPort,&QSerialPort::readyRead,this,&rs485_dev::serialPortReadyRead);
}

rs485_dev::~rs485_dev()
{
    this->serialPort->close();
}

/**
  @description:读取数据
*/
QByteArray rs485_dev::read_data_barray()
{
    this->read_data_ok = false;
    return this->read_buf;
}

char *rs485_dev::read_data_carr()
{
    return this->read_buf.data();
}

/**
  @description:串口发送数据
  @param - buf:发送数据缓冲区
  @return:发送的数据数，失败返回-1
*/
qint64 rs485_dev::write_data(QByteArray &buf)
{
    return this->serialPort->write(buf);
}

qint64 rs485_dev::write_data(const char *buf)
{
    return this->serialPort->write(buf);
}

void rs485_dev::serialPortReadyRead()
{
    this->read_data_ok = true;
    qint64 data_sz = this->serialPort->bytesAvailable();
//    cout << "humiture data_sz: " << data_sz << endl;
    for(qint8 i=0;i<data_sz;i++)
        this->read_buf.push_back(this->serialPort->read(1));
    this->read_data_sz += data_sz;
    if(recv_cnt == 0)
    {
        if(data_sz == 8 || data_sz == 1)
        {
            recv_cnt++;
        }
        else if(data_sz == 9)
        {
            recv_data_bit_len = data_sz;
            recv_cnt = 0;
            this->read_data_sz = 0;
        }
        emit newValue(this->read_buf);
    }
    else if(recv_cnt == 1)
    {
        if(this->read_data_sz == 16)
        {
            recv_data_bit_len = 8;
        }
        else if(this->read_data_sz == 9)
        {
            recv_data_bit_len = 9;
        }
        recv_cnt++;
        this->read_data_sz = 0;
        emit newValue(this->read_buf);
    }
}
